﻿package com.ui.manager
{
	import com.ui.drag.DragData;
	import com.bd.ScaleBitmapSprite;
	import com.net.AssetData;
	import com.ui.containers.Panel;
	import com.ui.containers.TitleWindow;
	import com.ui.controls.IUIComponent;
	import com.ui.controls.SguoTextField;
	import com.ui.core.UIComponent;
	import com.ui.layout.GLayout;
	import com.ui.skin.ASSkin;
	import com.utils.MathUtil;

	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageDisplayState;
	import flash.events.Event;
	import flash.events.FullScreenEvent;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.system.ApplicationDomain;
	import flash.system.Capabilities;
	import flash.text.StyleSheet;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;

	com.net.AssetData;
	/**
	 * UI Manager
	 * 
	 * @author Cafe
	 * @version 20100724
	 */
	public class UIManager {
		public static const SHADOW : DropShadowFilter = new DropShadowFilter(1, 45, 0, 0.5, 1, 1);
		private static var _defaultFont : String;
		private static var _defaultCSS : StyleSheet;
		private static var _root : Sprite;
		private static var _url : String = "unkown";
		private static var _top : Sprite;
		private static var _content : Sprite;
		private static var _swfName : String = "unkown.swf";
		private static var _dragModal : Sprite = ASSkin.emptySkin;
		private static var _stageOldWidth : int = 1000;
		private static var _stageOldHeight : int = 600;
		public static var stageOffset : Point = new Point();
		public static var uiList:Vector.<Sprite> = new Vector.<Sprite>;
		public static var dragData:DragData;

		public static function setUI(value : DisplayObject) : void {
			uiList.push(value);
		}

		public static function get top() : Sprite {
			return _top;
		}
		public static function stageResizeHandler(event : Event) : void {
			if (UIManager._root == null || _root.stage == null) return;
			var stage : Stage = _root.stage;
			var panel : Panel;
			var titleWindow : TitleWindow;
			for (var i : int = 0;i < UIManager._root.numChildren;i++) {
				var child : DisplayObject = UIManager._root.getChildAt(i);
				var component : UIComponent = child as UIComponent;
				if (component == null) continue;
				if (component.align == null) continue;
				if (component is Panel) {
					panel = component as Panel;
					if (panel.modal) panel.resizeModal();
				} else if (component is TitleWindow) {
					titleWindow = component as TitleWindow;
					if (titleWindow.modal) titleWindow.resizeModal();
				}
				GLayout.layout(component);
			}

			if (_dragModal.parent) {
				_dragModal.width = stage.stageWidth;
				_dragModal.height = stage.stageHeight;
			}
			stageOffset.x = 0;
			stageOffset.y = 0;
			_root.x = stageOffset.x;
			_root.y = stageOffset.y;
			if (stage && stage.displayState == StageDisplayState.FULL_SCREEN) {
				stageOffset.x = 0;
				stageOffset.y = 0;
				_root.x = stageOffset.x;
				_root.y = stageOffset.y;
				// return;
			}

			for (var k : int = 0; k < uiList.length; k++) {
				uiList[k].x = stageOffset.x;
				uiList[k].y = stageOffset.y;
				if (uiList[k] is UIComponent) {
					GLayout.layout(uiList[k]);
				}
				if (uiList[k] is Panel) {
					panel = uiList[k] as Panel;
					if (panel.modal) panel.resizeModal();
				} else if (uiList[k] is TitleWindow) {
					titleWindow = uiList[k] as TitleWindow;
					if (titleWindow.modal) titleWindow.resizeModal();
				}
				// uiResize(uiList[k]);
				resize(uiList[k] as Sprite);
			}
		}

		public static function resize(sp : Sprite) : void {
			var panel : Panel;
			var titleWindow : TitleWindow;
			var ui : DisplayObject;
			for (var i : int = 0; i < sp.numChildren; i++) {
				ui = sp.getChildAt(i);
				if (ui is UIComponent) {
					GLayout.layout(ui);
				}
				if (ui is Panel) {
					panel = ui as Panel;
					if (panel.modal) panel.resizeModal();
				} else if (ui is TitleWindow) {
					titleWindow = ui as TitleWindow;
					if (titleWindow.modal) titleWindow.resizeModal();
				}
			}
		}

		public static function uiResize(sp : Sprite) : void {
			var ui : DisplayObject;
			for (var i : int = 0; i < sp.numChildren; i++) {
				ui = sp.getChildAt(i);
				if (ui is IUIComponent)
					GLayout.layout(ui, IUIComponent(ui).align);
			}
		}

		public static function setRoot(value : Sprite, rootSp : Sprite = null, topSp : Sprite = null) : void {
			_content = value;
			_root = rootSp;
			_top = topSp;
			if (_root == null) _root = _content;
			else _content.addChild(_root);

			if (_top) {
				_top.name = "UiContainer";
				_content.addChild(_top);
				setUI(_top);
			}

			if (value.parent) {
				initRoot();
			} else {
				value.addEventListener(Event.ADDED_TO_STAGE, initRoot);
			}
		}

		private static function initRoot(event : Event = null) : void {
			_url = UIManager._root.loaderInfo.url;
			// _url =_root.loaderInfo.url;
			_swfName = UIManager._url.split("/").pop();
			_root.stage.addEventListener(Event.RESIZE, UIManager.stageResizeHandler);
			_root.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
			stageResizeHandler(new Event(Event.RESIZE));
			_dragModal.name = "dragModal";
		}

		private static function fullScreenHandler(event : FullScreenEvent) : void {
			if (event.fullScreen) {
				_root.x = 0 ;
				_root.y = 0;
			}
		}

		public static function get root() : Sprite {
			return UIManager._root;
		}

		public static function get url() : String {
			return UIManager._url;
		}

		public static function get swfName() : String {
			return UIManager._swfName;
		}

		public static function get defaultFont() : String {
			if (_defaultFont == null) {
				_defaultFont = "宋体";
				var os : String = Capabilities.os;
				if (os.indexOf("Mac") != -1) {
					_defaultFont = "华文黑体";
				} 
				/*
				else if (os.indexOf("Windows 7") != -1) {
				_defaultFont = "微软雅黑";
				} */ else if (os.indexOf("Linux") != -1) {
					_defaultFont = "AR PL UMing CN";
				}
			}
			return _defaultFont;
		}

		public static function get defaultCSS() : StyleSheet {
			if (_defaultCSS == null) {
				_defaultCSS = new StyleSheet();
				_defaultCSS.setStyle("a:active", {"fontSize":"13", "color":"#FF0000", "textDecoration":"underline"});
				_defaultCSS.setStyle("a:hover", {"fontSize":"13", "color":"#FFFFFF", "textDecoration":"underline"});
			}
			return _defaultCSS;
		}

		private static var filterCache : Dictionary = new Dictionary();

		public static function getEdgeFilters(edgeColor : uint, edgeAlpha : Number = 1) : Array {
			var key : String = String(edgeColor) + String(edgeAlpha);
			if (filterCache[key] == null)
				filterCache[key] = [new GlowFilter(edgeColor, edgeAlpha, 2, 2, 17, 1, false, false)];
			return filterCache[key];
		}

		public static function getOffset(value : DisplayObject) : Point {
			var rect : Rectangle = MathUtil.toIntRect(value.getBounds(value));
			return rect.topLeft;
		}

		public static function getNewClass(asset : AssetData) : * {
			if (asset == null) {
				return null;
			}
			var domain : ApplicationDomain = ApplicationDomain.currentDomain;
			if (domain.hasDefinition(asset.className)) {
				var classRef : Class = getDefinitionByName(asset.className) as Class;
				return new classRef();
			}
			return null;
		}

		private static function getRes(asset : AssetData, classType : Class = null) : * {
			if (asset == null) {
				return null;
			}
			var skin : *;
			if (asset.libId == AssetData.AS_LIB) {
				skin = ASSkin.getBy(asset);
			} else {
				var domain : ApplicationDomain = ApplicationDomain.currentDomain;
				if (domain.hasDefinition(asset.className)) {
					var classRef : Class = getDefinitionByName(asset.className) as Class;
					if (classType == null) {
						skin = new classRef();
					}
				}
				if (!skin) skin = ASSkin.getBy(asset);
				else if (skin is Sprite) skin.mouseEnabled = skin.mouseChildren = asset.mouseEnable;
			}
			if (skin.name == "errorSkin") {
				// trace(GStringUtil.format("UIManager:{0} not found!", asset.key));
			}
			return skin;
		}

		public static function getUI(asset : AssetData) : DisplayObject {
			if (asset && asset.isScaleBitmap) {
				return new ScaleBitmapSprite(getNewClass(asset), asset.inner, asset.outer);
			}
			return getRes(asset);
		}

		public static function createRect(color : uint, alpha : Number = 1) : Sprite {
			var skin : Sprite = new Sprite();
			skin.mouseEnabled = skin.mouseChildren = false;
			var g : Graphics = skin.graphics;
			g.beginFill(0, 1);
			g.drawRect(0, 0, 20, 20);
			g.endFill();
			g.beginFill(color, alpha);
			g.drawRect(1, 1, 18, 18);
			g.endFill();
			skin.scale9Grid = new Rectangle(1, 1, 18, 18);
			return skin;
		}

		public static function createBorder(color : uint = 0x000000) : Sprite {
			var skin : Sprite = new Sprite();
			skin.mouseEnabled = skin.mouseChildren = false;
			var g : Graphics = skin.graphics;
			g.beginFill(0, 0.2);
			g.drawRect(1, 1, 18, 18);
			g.endFill();
			g.beginFill(color, 1);
			g.drawRect(0, 0, 20, 1);
			g.endFill();
			g.beginFill(color, 1);
			g.drawRect(0, 1, 1, 18);
			g.endFill();
			g.beginFill(color, 1);
			g.drawRect(19, 1, 1, 18);
			g.endFill();
			g.beginFill(color, 1);
			g.drawRect(0, 19, 20, 1);
			g.endFill();
			skin.scale9Grid = new Rectangle(1, 1, 18, 18);
			return skin;
		}

		/**
		 * 获取字符串的字节长度
		 * 
		 * @param        str
		 * @return
		 */
		public static function getStringBytesLength(str : String) : int {
			var bytes : ByteArray = new ByteArray();
			bytes.writeMultiByte(str, "gb2312");
			bytes.position = 0;
			return bytes.length;
		}

		public static function createBar(color : uint = 0xFFFF00) : Sprite {
			var skin : Sprite = new Sprite();
			skin.mouseEnabled = skin.mouseChildren = false;
			var g : Graphics = skin.graphics;
			g.beginFill(0x000000, 1);
			g.drawRect(0, 0, 20, 20);
			g.endFill();
			g.beginFill(color, 1);
			g.drawRect(1, 1, 18, 18);
			g.endFill();
			g.beginFill(0xFFFFFF, 0.2);
			g.drawRect(1, 1, 18, 1);
			g.endFill();
			g.beginFill(0xFFFFFF, 0.2);
			g.drawRect(1, 1, 1, 18);
			g.endFill();
			g.beginFill(0xFFFFFF, 0.2);
			g.drawRect(18, 1, 1, 18);
			g.endFill();
			g.beginFill(0x000000, 0.2);
			g.drawRect(1, 18, 18, 1);
			g.endFill();
			skin.scale9Grid = new Rectangle(2, 2, 16, 16);
			return skin;
		}

		public static function getMask() : Sprite {
			var mask : Sprite = new Sprite();
			mask.mouseEnabled = false;
			var g : Graphics = mask.graphics;
			g.beginFill(0x0000FF, 1);
			g.drawRect(0, 0, 10, 10);
			g.endFill();
			return mask;
		}

		public static function getTextFormat() : TextFormat {
			var textFormat : TextFormat = new TextFormat();
			textFormat.font = UIManager.defaultFont;
			textFormat.size = 13;
			textFormat.color = 0xffffff;
			return textFormat;
		}

		public static function getTextField() : TextField {
			var textField : SguoTextField = new SguoTextField();
			textField.width = 0;
			textField.text = "?";
			textField.height = textField.textHeight + 4;
			textField.text = "";
			return textField;
		}

		public static function getInputTextField() : TextField {
			var textField : TextField = new TextField();
			textField.defaultTextFormat = UIManager.getTextFormat();
			textField.text = "?";
			textField.height = textField.textHeight + 4;
			textField.text = "";
			textField.tabEnabled = true;
			textField.type = TextFieldType.INPUT;
			return textField;
		}

		public static function atParent(source : DisplayObject, target : DisplayObject) : Boolean {
			if (source == null || target == null) return false;
			if (source == target) return true;
			var parent : DisplayObjectContainer = source.parent;
			while (parent != null) {
				if (parent == target) {
					return true;
				}
				parent = parent.parent;
			}
			return false;
		}

		public static function hitTest(x : int, y : int) : DisplayObject {
			if (!_root) return null;
			var result : Array = _root.getObjectsUnderPoint(new Point(x, y));
			if (!result) return null;
			var index : int = result.indexOf(_dragModal);
			if (index != -1) result.splice(index, 1);
			if (result.length == 0) return null;
			return result.pop();
		}

		public static function set dragModal(value : Boolean) : void {
			if (value) {
				if (!_dragModal.parent) {
					_dragModal.width = _root.stage.stageWidth;
					_dragModal.height = _root.stage.stageHeight;
					_dragModal.mouseEnabled = _dragModal.mouseChildren = true;
					_root.addChild(_dragModal);
				}
			} else {
				if (_dragModal.parent) {
					_dragModal.parent.removeChild(_dragModal);
				}
			}
		}
	}
}